////////////////////////////////////////////////
// DESCRIPTION:
//    FusionWare defined control code definitions
//
// Legal Notices:
//     Copyright (c) 2008, Telliam Consulting, LLC.
//     All rights reserved.
//
//     Redistribution and use in source and binary forms, with or without modification,
//     are permitted provided that the following conditions are met:
//
//     * Redistributions of source code must retain the above copyright notice,
//       this list of conditions and the following disclaimer.
//
//     * Redistributions in binary form must reproduce the above copyright notice,
//       this list of conditions and the following disclaimer in the documentation
//       and/or other materials provided with the distribution.
//
//     * Neither the name of Telliam Consulting nor the names of its contributors
//       may be used to endorse or promote products derived from this software
//       without specific prior written permission.
//
// Disclaimer:
//     THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
//     ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
//     WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
//     IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
//     INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
//     BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
//     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
//     LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
//     OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
//     OF THE POSSIBILITY OF SUCH DAMAGE.  
//
#pragma once

#include <wtypes.h>
#include <WinIoctl.h>

namespace FusionWare
{
    // Group = IO Control Codes

    // Microsoft defined OEM Control and function codes for use with
    // CTL_CODE macro for generating IOCTL_xxx codes.
    //
    // Unfortunately MS neglected to define the OEM value ranges in
    // the headers so that is done here. 
    //
    //
    // A Control code is a 32 bit value with the following bit mask:
    // 3                      1                1                   0                 0
    // 2                      6                4                   2                 0
    // +----------------------+----------------+-------------------+-----------------+
    // | DeviceType (16 bits) | Access (2 bits)| Function (12 bits)| Method (2 bits) |
    // +----------------------+----------------+-------------------+-----------------+


    // {internal}
    // Base Device code value for use by EmbeddedFusion. Microsoft reserves all values
    // from 0 to 32767
    const UINT32 FILE_DEVICE_FUSIONWARE = 32768;

    // {internal}
    // FusionWare::BSP reserves 1024 ids
    const UINT32 FILE_DEVICE_FUSIONWARE_RESERVED = 0x400;

    // Add new FusionWare defined File Device types here using
    // the folowing form.
    //
    // const UINT32 FILE_DEVICE_xxxx = (FILE_DEVICE_FUSIONWARE + ... );
    //
    // *DO NOT* define File device types anywhere else! Putting
    //  them all here makes sure there are no conflicts among 
    //  any of the FusionWare defined devices. 

    // Description:
    //    Device Control Code definition for KlibIoControl
    //
    // Remarks:
    //    Technically KLibIoControl uses a completely seperate "namespace" from the
    //    other control codes [Sigh!] but to maintain some sanity and consistnecy
    //    this is defined such that there is no conflict with the MS reserved
    //    KLIB control codes (0-256)
    //
    const UINT32 FILE_DEVICE_KLIB = (FILE_DEVICE_FUSIONWARE + 0 );

    // filedevice for the FusionWare Common Installable ISR Support
    const UINT32 FILE_DEVICE_FUSIONWARE_IISR = (FILE_DEVICE_FUSIONWARE + 1 );

    // File device for Touch and battery ADC controllers
    // See Also:
    //    FusionWare::DFX::Touch
    //
    const UINT32 FILE_DEVICE_TOUCH_ADC = (FILE_DEVICE_FUSIONWARE + 2);

    // File Device for FMD based Block devices for custom control codes
    // the MS defined IOCTL_FMD codes are all based on FILE_DEVICE_DISK
    // so anything using this file device won't conflict with the MS
    // defined user disk codes. 
    const UINT32 FILE_DEVICE_FMD = (FILE_DEVICE_FUSIONWARE + 3);
    
    // filedevice for the Drivers to query if a resource is avilable for use.
    // commonly used by (debug\) serial drivers
    const UINT32 FILE_DEVICE_FUSIONWARE_RES_MNGR = (FILE_DEVICE_FUSIONWARE + 4 );

    // {internal}
    // Base Function code value for use by OEMs. Microsoft reserves all values
    // from 0 to 0x7FF
    // FusionWare::BSP resserves values from 0x800 - 0xA00
    // for all BSPs based on the common library
    const UINT32 CTL_FUNC_FUSIONWARE = 0x800;

    // {internal}
    // FusionWare::BSP reserves 512 ids
    const UINT32 CTL_FUNC_FUSIONWARE_RESERVED = 0x200;

    ///////////////////////////////////////////////////////
    // {internal}
    // Description: 
    //    Defines a FusionWare specific control code
    //
    // Input: 
    //    f - FILE_DEVICE_xxx value to use for the device
    //    x - offset from base of device function codes
    //
    // Returns: 
    //    IoControl Code 
    //     
    // Remarks: 
    //    Function control codes must be unique unique for
    //    each FILE_DEVICE_xxx but may be duplicated from one
    //    FILE_DEIVCE_xxx to another. A Unique control code
    //    is the combination of FILE_DEVICE_xxx and the
    //    CTL_FUNC_xxx sub code. 
    //   
    // Note: 
    //    This macro is reserved for use in defining
    //    FusionWare Specifc control codes.  OEMs
    //    *MUST NOT* use this directly as the FusionWare
    //    development team may define control codes for
    //    it's use at any time in the future.
    //
    #define DEVICE_CTL_CODE_FUSIONWARE(f,x) CTL_CODE((f), FusionWare::CTL_FUNC_FUSIONWARE + (x), METHOD_BUFFERED, FILE_READ_ACCESS)

    // {internal}
    #define CTL_CODE_HAL_FUSIONWARE(x)  DEVICE_CTL_CODE_FUSIONWARE( FILE_DEVICE_HAL, (x))

    // {internal}
    #define CTL_CODE_KLIB_FUSIONWARE(x) DEVICE_CTL_CODE_FUSIONWARE( FusionWare::FILE_DEVICE_KLIB, (x))

    // {internal}
    #define CTL_CODE_FUSIONWARE_IISR(x) DEVICE_CTL_CODE_FUSIONWARE( FusionWare::FILE_DEVICE_FUSIONWARE_IISR, (x))
    
    // {internal}
    #define CTL_CODE_FUSIONWARE_RES_MNGR(x) DEVICE_CTL_CODE_FUSIONWARE( FusionWare::FILE_DEVICE_FUSIONWARE_RES_MNGR, (x))

    // {internal}
    // Sets the SYSINTR value for the ISR to use
    const UINT32 IOCTL_IISR_SYSINTR = CTL_CODE_FUSIONWARE_IISR(0);

    // {internal}
    // Sends the ISR info to the Kernel mode handler
    const UINT32 IOCTL_IISR_INFO = CTL_CODE_FUSIONWARE_IISR(1);

    // {internal}
    // Asks the OAL if a resource is used by the OAL
    const UINT32 IOCTL_RES_AVAILABLE = CTL_CODE_FUSIONWARE_RES_MNGR(0);

    ///////////////////////////////////////////////////////
    // {internal}
    // Description: 
    //    Sets the interrupt mode for a device 
    // 
    // Input: 
    //    pInBuf    - pointer to an EnableIntData structure
    //    InBufSize - sizeof(EnableIntData)
    //
    // Returns: 
    //    BOOL 
    //     
    // Remarks: 
    //    This control code is used to set the interrupt mode for 
    //    a device. 
    //
    // Note: 
    //    The standard FusionWare::DFX.h safely wraps this control code
    //    with a set of inline functions. Thus there is no need to
    //    use this code directly. 
    //
    // See Also:
    //    FusionWare::DFX::SetIrqMode
    //
    const UINT32 IOCTL_HAL_SETINTMODE = CTL_CODE_HAL_FUSIONWARE( 2 );

    ///////////////////////////////////////////////////////
    // Description: 
    //    Sets the GPIO Pin
    // 
    // Input: 
    //    pInBuf - (DWORD) pin number
    //
    // Remarks: 
    //    This control code is used by CPUs that don't have
    //    independent set and clear registers for atomic
    //    changes in the pin state in hardware.
    //
    const UINT32 IOCTL_HAL_GPIO_SETPIN = CTL_CODE_HAL_FUSIONWARE( 3 );

    ///////////////////////////////////////////////////////
    // Description: 
    //    Clears the GPIO Pin
    // 
    // Input: 
    //    pInBuf - (DWORD) pin number
    //
    // Remarks: 
    //    This control code is used by CPUs that don't have
    //    independent set and clear registers for atomic
    //    changes in the pin state in hardware.
    //
    const IOCTL_HAL_GPIO_CLEARPIN = CTL_CODE_HAL_FUSIONWARE( 4 );


    // {Group:OEM Control Code Constants}
    //
    // Base value for OEMs to offset device values from
    // See Also: DEVICE_CTL_CODE_OEM, CTL_CODE_HAL_OEM 
    const UINT32 CTL_DEVICE_OEM = (FILE_DEVICE_FUSIONWARE + FILE_DEVICE_FUSIONWARE_RESERVED);

    // {Group:OEM Control Code Constants}
    //
    // Base value for OEMs to offset function values from
    // See Also: DEVICE_CTL_CODE_OEM, CTL_CODE_HAL_OEM 
    const UINT32 CTL_FUNC_OEM = (CTL_FUNC_FUSIONWARE + CTL_FUNC_FUSIONWARE_RESERVED);

    ///////////////////////////////////////////////////////
    // Description: 
    //    Builds an OEM device Control Code
    //
    // Input: 
    //    f - FILE_DEVICE_xxx value to use for the device
    //    x - offset from base of device function codes
    //
    // Returns: 
    //    IoControl Code 
    //     
    // Remarks: 
    //    Function control codes must be unique unique for
    //    each FILE_DEVICE_xxx but may be duplicated from one
    //    FILE_DEIVCE_xxx to another. A Unique control code
    //    is the combination of FILE_DEVICE_xxx and the
    //    CTL_FUNC_xxx sub code. OEMs MUST use FILE_DEVICE_xxx
    //    that are based off FILE_DEVICE_OEM. 
    //
    //    Under Windows CE METHOD and Access fields of a control
    //    code are ignored and should always be set to
    //    METHOD_BUFFERED and FILE_READ_ACCESS. This macro
    //    takes care of that automatically.
    //   
    // {Group:FusionWare\OEM Control Code Macros}
    #define DEVICE_CTL_CODE_OEM(f,x) CTL_CODE((f), FusionWare::CTL_FUNC_OEM + (x), METHOD_BUFFERED, FILE_READ_ACCESS)

    // {Group:FusionWare\OEM Control Code Macros}
    // Defines OEM specifc OAL codes for use with KernelIoControl
    #define HAL_CTL_CODE_OEM(x) DEVICE_CTL_CODE_OEM( FILE_DEVICE_HAL, (x))

    namespace DFX
    {
        namespace Display
        {
            // MS reserves 0 - 99,9999 for Display driver DrvEscape codes.
            // so this is a semi-arbitrary choice...
            const UINT32 DRVESC_OEM = 100000;

            // Allows re-initialization of a controller
            // typically the driver reads settings from the registry
            // that are changed. This is useful in development and testing
            // as it allows "tweaking" hardware settings without re-booting
            // the full OS
            const UINT32 DRVESC_REINIT = (DRVESC_OEM + 1);

            // new standard command for backlight control
            // works identical to CONTRASTCOMMAND
            const UINT32 BACKLIGHTCOMMAND = (DRVESC_OEM + 2);

            // turns the cursor ON - useful for touch based
            // devices with USB host controllers that
            // intend to support a USB mouse.
            const UINT32 DRVESC_CURSOR_ON = (DRVESC_OEM + 3);

            // turns the cursor Off - useful for touch based
            // devices with USB host controllers that
            // intend to support a USB mouse.
            const UINT32 DRVESC_CURSOR_OFF = (DRVESC_OEM + 4);

            // The BACKLIGHTCOMMAND DrvEscape is used to get/set the backlight
            // on the display controlled by the driver being called. The input
            // parameter shoud be a BacklightCmdInputParm structure. Its output
            // parameter should be an int. If the command completes successfully
            // the DrvEscape should return TRUE, otherwise it should return FALSE.
            // These are really just clones of the contrast commnands renamed
            // for the backlight.
            //
            enum BacklightCommands
            {
                BACKLIGHT_CMD_GET      = 0, // Parm=Ignored, Out=Current setting
                BACKLIGHT_CMD_SET      = 1, // Parm=NewSet,  Out=Resulting setting
                BACKLIGHT_CMD_INCREASE = 2, // Parm=Amount,  Out=Resulting setting
                BACKLIGHT_CMD_DECREASE = 3, // Parm=Amount,  Out=Resulting setting
                BACKLIGHT_CMD_DEFAULT  = 4, // Parm=Ignored, Out=Resulting setting
                BACKLIGHT_CMD_MAX      = 5, // Parm=Ignored, Out=Max value
            };

            // Define the Backlight data parms identical to MS defined contrast
            typedef struct ContrastCmdInputParm BacklightCmdInputParm;
        }
    }
}
